package net.cyue.util;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.*;

public class ByteStringConverter {

    // 转义字符映射表
    private static final Map<Character, Character> ESCAPE_MAP = new HashMap<>();
    static {
        ESCAPE_MAP.put('n', '\n');
        ESCAPE_MAP.put('t', '\t');
        ESCAPE_MAP.put('r', '\r');
        ESCAPE_MAP.put('b', '\b');
        ESCAPE_MAP.put('f', '\f');
        ESCAPE_MAP.put('\'', '\'');
        ESCAPE_MAP.put('"', '"');
        ESCAPE_MAP.put('\\', '\\');
    }

    // region 原有Unicode转换方法
    /**
     * 将包含转义序列的字符串转换为普通字符串
     * @param escapedStr 包含转义序列的字符串
     * @return 转换后的普通字符串
     */
    public static String unescape(String escapedStr) {
        if (escapedStr == null || escapedStr.isEmpty()) {
            return escapedStr;
        }

        StringBuilder sb = new StringBuilder();
        int length = escapedStr.length();
        for (int i = 0; i < length; ) {
            char currentChar = escapedStr.charAt(i);
            if (currentChar == '\\' && i + 1 < length) {
                char nextChar = escapedStr.charAt(i + 1);

                // 处理Unicode转义序列(\\uXXXX)
                if (nextChar == 'u' && i + 5 < length) {
                    try {
                        String hex = escapedStr.substring(i + 2, i + 6);
                        validateHexEscape(hex, 0xFFFF, "u");
                        int codePoint = Integer.parseInt(hex, 16);
                        sb.append((char) codePoint);
                        i += 6;
                        continue;
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Invalid \\u escape sequence: \\u" +
                                escapedStr.substring(i + 2, Math.min(i + 6, length)));
                    }
                }

                // 处理十六进制转义序列(\\xXX)
                if (nextChar == 'x' && i + 3 < length) {
                    try {
                        String hex = escapedStr.substring(i + 2, i + 4);
                        validateHexEscape(hex, 0xFF, "x");
                        int codePoint = Integer.parseInt(hex, 16);
                        sb.append((char) codePoint);
                        i += 4;
                        continue;
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Invalid \\x escape sequence: \\x" +
                                escapedStr.substring(i + 2, Math.min(i + 4, length)));
                    }
                }

                // 处理其他转义序列
                if (ESCAPE_MAP.containsKey(nextChar)) {
                    sb.append(ESCAPE_MAP.get(nextChar));
                    i += 2;
                    continue;
                }
            }
            sb.append(currentChar);
            i++;
        }
        return sb.toString();
    }

    /**
     * 将普通字符串转换为转义序列形式
     * @param str 普通字符串
     * @return 包含转义序列的字符串
     */
    public static String escape(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            switch (c) {
                case '\n': sb.append("\\n"); break;
                case '\t': sb.append("\\t"); break;
                case '\r': sb.append("\\r"); break;
                case '\b': sb.append("\\b"); break;
                case '\f': sb.append("\\f"); break;
                case '\'': sb.append("\\'"); break;
                case '"': sb.append("\\\""); break;
                case '\\': sb.append("\\\\"); break;
                default:
                    if (c <= 31 || c >= 127) {
                        // 优先使用短格式的十六进制转义(\xXX)如果可能
                        if (c <= 0xFF) {
                            sb.append(String.format("\\x%02x", (int) c));
                        } else {
                            sb.append(String.format("\\u%04x", (int) c));
                        }
                    } else {
                        sb.append(c);
                    }
            }
        }
        return sb.toString();
    }
    // endregion

    // region Python字节字符串转换方法
    /**
     * 将Python字节字符串(b'...')转换为Java转义字符串
     * 示例：b'\\x41\\x42' → "\x41\x42"
     */
    public static String convertPythonBytesToJavaString(String pythonBytes) {
        if (pythonBytes == null || !pythonBytes.startsWith("b'") || !pythonBytes.endsWith("'")) {
            throw new IllegalArgumentException("Invalid Python byte string format");
        }

        // 提取引号内的内容
        String content = pythonBytes.substring(2, pythonBytes.length() - 1);

        // 处理转义序列
        StringBuilder result = new StringBuilder();
        Matcher matcher = Pattern.compile("(\\\\x[0-9a-fA-F]{2}|\\\\[\\\\'\"nrtbf]|.)").matcher(content);

        while (matcher.find()) {
            String group = matcher.group();
            if (group.startsWith("\\x")) {
                // 保持\x转义不变
                result.append(group);
            } else if (group.startsWith("\\")) {
                // 处理其他转义
                switch (group) {
                    case "\\\\": result.append("\\\\"); break;
                    case "\\'": result.append("\\'"); break;
                    case "\\\"": result.append("\\\""); break;
                    case "\\n": result.append("\\n"); break;
                    case "\\r": result.append("\\r"); break;
                    case "\\t": result.append("\\t"); break;
                    case "\\b": result.append("\\b"); break;
                    case "\\f": result.append("\\f"); break;
                    default: throw new IllegalArgumentException("Invalid escape sequence: " + group);
                }
            } else {
                // 普通字符直接添加
                result.append(group);
            }
        }

        return result.toString();
    }

    /**
     * 将Java转义字符串转换为Python字节字符串
     * 示例："\x41\x42" → b'\x41\x42'
     */
    public static String convertJavaStringToPythonBytes(String javaString) {
        if (javaString == null) {
            throw new IllegalArgumentException("Input cannot be null");
        }

        StringBuilder result = new StringBuilder("b'");
        for (int i = 0; i < javaString.length(); ) {
            char c = javaString.charAt(i);
            if (c == '\\' && i + 1 < javaString.length()) {
                char next = javaString.charAt(i + 1);
                if (next == 'x' && i + 3 < javaString.length()) {
                    // 处理\x转义
                    String hex = javaString.substring(i, i + 4);
                    result.append(hex);
                    i += 4;
                } else {
                    // 处理其他转义
                    switch (next) {
                        case '\\': result.append("\\\\"); break;
                        case '\'': result.append("\\'"); break;
                        case '"': result.append("\\\""); break;
                        case 'n': result.append("\\n"); break;
                        case 'r': result.append("\\r"); break;
                        case 't': result.append("\\t"); break;
                        case 'b': result.append("\\b"); break;
                        case 'f': result.append("\\f"); break;
                        default: throw new IllegalArgumentException("Invalid escape sequence: \\" + next);
                    }
                    i += 2;
                }
            } else {
                // 普通字符
                if (c == '\'') {
                    result.append("\\'");
                } else {
                    result.append(c);
                }
                i++;
            }
        }
        result.append("'");
        return result.toString();
    }
    // endregion

    // region 辅助方法
    private static void validateHexEscape(String hex, int maxValue, String prefix) {
        try {
            int value = Integer.parseInt(hex, 16);
            if (value > maxValue) {
                throw new IllegalArgumentException(
                        String.format("\\%s escape sequence value out of range (0-%d): \\%s%s",
                                prefix, maxValue, prefix, hex));
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    String.format("Invalid \\%s escape sequence: \\%s%s",
                            prefix, prefix, hex));
        }
    }
}
